package strategy

import (
	"context"
	"fmt"
	"sync"
	"time"

	"github.com/gogf/gf/v2/container/gmap"
	"github.com/gogf/gf/v2/os/gtimer"

	"goldtree/utility/logger"
)

// Manager 策略管理器
type Manager struct {
	strategies  *gmap.StrAnyMap     // 策略实例映射
	configs     *gmap.IntAnyMap     // 策略配置映射
	timers      *gmap.IntAnyMap     // 定时器映射
	dataChannel chan *MarketData    // 市场数据通道
	signalChannel chan *Signal      // 信号通道
	running     bool                // 是否运行中
	logger      *logger.Logger      // 日志器
	mutex       sync.RWMutex        // 读写锁
}

// NewManager 创建策略管理器
func NewManager() *Manager {
	return &Manager{
		strategies:    gmap.NewStrAnyMap(true),
		configs:       gmap.NewIntAnyMap(true),
		timers:        gmap.NewIntAnyMap(true),
		dataChannel:   make(chan *MarketData, 1000),
		signalChannel: make(chan *Signal, 1000),
		running:       false,
		logger:        logger.New("strategy_manager"),
	}
}

// RegisterStrategy 注册策略
func (m *Manager) RegisterStrategy(strategyType string, factory func() Strategy) error {
	if strategyType == "" {
		return fmt.Errorf("策略类型不能为空")
	}
	
	// 创建策略实例验证
	strategy := factory()
	if strategy == nil {
		return fmt.Errorf("策略工厂函数返回nil")
	}
	
	m.strategies.Set(strategyType, factory)
	m.logger.Info(context.Background(), "策略类型注册成功", "type", strategyType)
	return nil
}

// CreateStrategy 创建策略实例
func (m *Manager) CreateStrategy(config *StrategyConfig) (Strategy, error) {
	if config == nil {
		return nil, fmt.Errorf("策略配置不能为空")
	}
	
	factory := m.strategies.Get(config.Type)
	if factory == nil {
		return nil, fmt.Errorf("未知的策略类型: %s", config.Type)
	}
	
	strategyFactory, ok := factory.(func() Strategy)
	if !ok {
		return nil, fmt.Errorf("策略工厂函数类型错误")
	}
	
	strategy := strategyFactory()
	if strategy == nil {
		return nil, fmt.Errorf("创建策略实例失败")
	}
	
	// 验证策略配置
	if err := strategy.Validate(config); err != nil {
		return nil, fmt.Errorf("策略配置验证失败: %v", err)
	}
	
	// 初始化策略
	ctx := context.Background()
	if err := strategy.Initialize(ctx, config); err != nil {
		return nil, fmt.Errorf("策略初始化失败: %v", err)
	}
	
	m.configs.Set(config.ID, config)
	m.logger.Info(ctx, "策略实例创建成功", "id", config.ID, "name", config.Name, "type", config.Type)
	return strategy, nil
}

// StartStrategy 启动策略
func (m *Manager) StartStrategy(strategyID int) error {
	config := m.configs.Get(strategyID)
	if config == nil {
		return fmt.Errorf("策略配置不存在: %d", strategyID)
	}
	
	strategyConfig, ok := config.(*StrategyConfig)
	if !ok {
		return fmt.Errorf("策略配置类型错误")
	}
	
	strategy, err := m.CreateStrategy(strategyConfig)
	if err != nil {
		return fmt.Errorf("创建策略实例失败: %v", err)
	}
	
	ctx := context.Background()
	
	// 启动策略
	if err := strategy.Start(ctx); err != nil {
		return fmt.Errorf("启动策略失败: %v", err)
	}
	
	// 设置定时器
	if timer := m.timers.Get(strategyID); timer != nil {
		if t, ok := timer.(*gtimer.Entry); ok {
			t.Close()
		}
	}
	
	// 创建新的定时器
	timer := gtimer.AddSingleton(ctx, time.Minute, func(ctx context.Context) {
		if err := strategy.OnTimer(ctx); err != nil {
			strategy.OnError(ctx, err)
			m.logger.Error(ctx, "策略定时器执行失败", "id", strategyID, "error", err)
		}
	})
	
	m.timers.Set(strategyID, timer)
	m.logger.Info(ctx, "策略启动成功", "id", strategyID, "name", strategyConfig.Name)
	return nil
}

// StopStrategy 停止策略
func (m *Manager) StopStrategy(strategyID int) error {
	config := m.configs.Get(strategyID)
	if config == nil {
		return fmt.Errorf("策略配置不存在: %d", strategyID)
	}
	
	// 停止定时器
	if timer := m.timers.Get(strategyID); timer != nil {
		if t, ok := timer.(*gtimer.Entry); ok {
			t.Close()
		}
		m.timers.Remove(strategyID)
	}
	
	ctx := context.Background()
	m.logger.Info(ctx, "策略停止成功", "id", strategyID)
	return nil
}

// GetStrategyStatus 获取策略状态
func (m *Manager) GetStrategyStatus(strategyID int) (*StrategyContext, error) {
	config := m.configs.Get(strategyID)
	if config == nil {
		return nil, fmt.Errorf("策略配置不存在: %d", strategyID)
	}
	
	strategyConfig, ok := config.(*StrategyConfig)
	if !ok {
		return nil, fmt.Errorf("策略配置类型错误")
	}
	
	// 这里应该从实际运行的策略实例中获取状态
	// 为了演示，返回一个基本的状态
	context := &StrategyContext{
		Config:      strategyConfig,
		Status:      StatusIdle,
		RunCount:    0,
		ErrorCount:  0,
		RuntimeData: make(map[string]interface{}),
		Positions:   make(map[string]*Position),
		Performance: &StrategyPerformance{},
	}
	
	return context, nil
}

// ListStrategies 列出所有策略
func (m *Manager) ListStrategies() []*StrategyConfig {
	var configs []*StrategyConfig
	m.configs.Iterator(func(k int, v interface{}) bool {
		if config, ok := v.(*StrategyConfig); ok {
			configs = append(configs, config)
		}
		return true
	})
	return configs
}

// AddStrategyConfig 添加策略配置
func (m *Manager) AddStrategyConfig(config *StrategyConfig) error {
	if config == nil {
		return fmt.Errorf("策略配置不能为空")
	}
	
	if config.ID == 0 {
		return fmt.Errorf("策略ID不能为0")
	}
	
	if m.configs.Contains(config.ID) {
		return fmt.Errorf("策略ID已存在: %d", config.ID)
	}
	
	m.configs.Set(config.ID, config)
	m.logger.Info(context.Background(), "策略配置添加成功", "id", config.ID, "name", config.Name)
	return nil
}

// UpdateStrategyConfig 更新策略配置
func (m *Manager) UpdateStrategyConfig(config *StrategyConfig) error {
	if config == nil {
		return fmt.Errorf("策略配置不能为空")
	}
	
	if !m.configs.Contains(config.ID) {
		return fmt.Errorf("策略配置不存在: %d", config.ID)
	}
	
	m.configs.Set(config.ID, config)
	m.logger.Info(context.Background(), "策略配置更新成功", "id", config.ID, "name", config.Name)
	return nil
}

// RemoveStrategyConfig 移除策略配置
func (m *Manager) RemoveStrategyConfig(strategyID int) error {
	if !m.configs.Contains(strategyID) {
		return fmt.Errorf("策略配置不存在: %d", strategyID)
	}
	
	// 先停止策略
	if err := m.StopStrategy(strategyID); err != nil {
		m.logger.Warn(context.Background(), "停止策略失败", "id", strategyID, "error", err)
	}
	
	m.configs.Remove(strategyID)
	m.logger.Info(context.Background(), "策略配置移除成功", "id", strategyID)
	return nil
}

// Start 启动管理器
func (m *Manager) Start(ctx context.Context) error {
	m.mutex.Lock()
	defer m.mutex.Unlock()
	
	if m.running {
		return fmt.Errorf("策略管理器已在运行")
	}
	
	m.running = true
	
	// 启动数据处理协程
	go m.processMarketData(ctx)
	go m.processSignals(ctx)
	
	m.logger.Info(ctx, "策略管理器启动成功")
	return nil
}

// Stop 停止管理器
func (m *Manager) Stop(ctx context.Context) error {
	m.mutex.Lock()
	defer m.mutex.Unlock()
	
	if !m.running {
		return fmt.Errorf("策略管理器未在运行")
	}
	
	m.running = false
	
	// 停止所有策略
	m.configs.Iterator(func(k int, v interface{}) bool {
		if err := m.StopStrategy(k); err != nil {
			m.logger.Error(ctx, "停止策略失败", "id", k, "error", err)
		}
		return true
	})
	
	// 关闭通道
	close(m.dataChannel)
	close(m.signalChannel)
	
	m.logger.Info(ctx, "策略管理器停止成功")
	return nil
}

// SendMarketData 发送市场数据
func (m *Manager) SendMarketData(data *MarketData) {
	if m.running && data != nil {
		select {
		case m.dataChannel <- data:
		default:
			m.logger.Warn(context.Background(), "市场数据通道已满，丢弃数据")
		}
	}
}

// processMarketData 处理市场数据
func (m *Manager) processMarketData(ctx context.Context) {
	for {
		select {
		case <-ctx.Done():
			return
		case data, ok := <-m.dataChannel:
			if !ok {
				return
			}
			
			// 将数据发送给所有运行中的策略
			m.configs.Iterator(func(k int, v interface{}) bool {
				if config, ok := v.(*StrategyConfig); ok && config.IsActive {
					// 这里应该调用实际的策略实例
					// 为了演示，我们记录日志
					m.logger.Debug(ctx, "处理市场数据", "strategy_id", k, "stock_code", data.StockCode)
				}
				return true
			})
		}
	}
}

// processSignals 处理交易信号
func (m *Manager) processSignals(ctx context.Context) {
	for {
		select {
		case <-ctx.Done():
			return
		case signal, ok := <-m.signalChannel:
			if !ok {
				return
			}
			
			m.logger.Info(ctx, "收到交易信号", 
				"strategy_id", signal.StrategyID,
				"stock_code", signal.StockCode,
				"signal_type", signal.SignalType,
				"price", signal.Price,
				"confidence", signal.Confidence)
		}
	}
}

// GetRegisteredStrategies 获取已注册的策略类型
func (m *Manager) GetRegisteredStrategies() []string {
	var types []string
	m.strategies.Iterator(func(k string, v interface{}) bool {
		types = append(types, k)
		return true
	})
	return types
}

// IsRunning 检查管理器是否运行中
func (m *Manager) IsRunning() bool {
	m.mutex.RLock()
	defer m.mutex.RUnlock()
	return m.running
}